package com.chuangke.dev.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chuangke.common.idgen.IdManager;
import com.chuangke.dev.constant.GenConstants;
import com.chuangke.dev.dao.SysFormModelMapper;
import com.chuangke.dev.model.SysFormModel;
import com.chuangke.dev.model.SysModelTable;
import com.chuangke.dev.service.SysFormModelService;
import com.chuangke.dev.service.SysModelTableService;
import com.chuangke.dev.util.VelocityInitializer;
import com.chuangke.dev.util.VelocityUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class SysFormModelServiceImpl extends ServiceImpl<SysFormModelMapper, SysFormModel> implements SysFormModelService {

    @Autowired
    private SysFormModelMapper sysFormModelMapper;

    @Autowired
    private SysModelTableService sysModelTableService;

    @Override
    public List<SysFormModel> selectSysFormModelList(String name) {
        return sysFormModelMapper.selectList(new QueryWrapper<SysFormModel>().lambda().like(SysFormModel::getModelName, name));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdateSysFormModel(SysFormModel sysFormModel) {
        String id = sysFormModel.getId();
        if (id == null || id.trim().isEmpty()) {
            sysFormModel.setId(IdManager.nextId());
        }
        return this.saveOrUpdate(sysFormModel);
    }

    @Override
    public int deleteSysFormModelByIds(List<String> ids) {
        return sysFormModelMapper.deleteByIds(ids);
    }

    @Override
    public Map<String, byte[]> generatorFormModelCode(String[] modelIds) {
        Map<String, byte[]> fileMap = new HashMap<>();
        for (String modelId : modelIds) {
            fileMap.putAll(generatorFormModelCode(modelId));
        }
        return fileMap;
    }

    public Map<String, byte[]> generatorFormModelCode(String modelId) {
        SysFormModel formModel = sysFormModelMapper.selectOne(new QueryWrapper<SysFormModel>().lambda().eq(SysFormModel::getId, modelId));
        Map<String, byte[]> fileMap = new HashMap<>();
        //获取table
        SysModelTable headTable = sysModelTableService.loadModelByName(formModel.getHeadTableId());
        SysModelTable flTable = sysModelTableService.loadModelByName(formModel.getFlTableId());
        SysModelTable mxTable = sysModelTableService.loadModelByName(formModel.getMxTableId());

        VelocityInitializer.initVelocity();

        VelocityContext context = VelocityUtils.prepareFormContext(headTable, flTable, mxTable);
        String type = formModel.getModelType();
        String tplCategory = GenConstants.TPL_CRUD;
        if (Objects.equals(type, GenConstants.MODEL_TYPE)) {
            tplCategory = GenConstants.TPL_FORMMODEL;
        }
        List<String> templates = VelocityUtils.getTemplateList(tplCategory);
        for (String template : templates) {
            try (StringWriter sw = new StringWriter()) {
                Template tpl = Velocity.getTemplate(template, "UTF-8");
                tpl.merge(context, sw);
                String fileName = VelocityUtils.getFileName(template, headTable);

                fileMap.put(fileName, sw.toString().getBytes());
            } catch (IOException e) {
                log.error("渲染模板失败，表名：" + headTable.getTableName(), e);
            }
        }

        return fileMap;
    }
}
